iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Software Development

Rails Active Model系列 第 22

D-22 自訂義 form_for 的 form builder!

  • 分享至 

  • xImage
  •  

其實 Rails 裡面暗藏了很多可以自行定義的東西,像我們前面介紹過 validator、attribute 資料轉換器、callbacks 等等。

這次要來介紹的是,在 view 裡面常用到的 helper method form_for or form_with 可以配合使用的 自訂義 form builder!

其實很簡單,說破不值錢。
只要像這樣建立一個 class 繼承自 ActionView::Helpers::FormBuilder,就可以在裡面加上您自定義的 form method:

class MyFormBuilder < ActionView::Helpers::FormBuilder
  def give_me_five
    "其實是手掌的 emoji 只是這邊不知道為什麼顯示不出來"
  end
end

然後在 form_for 的 options 裡面加上 key :builder 並把你的 form builder class 指定進去,並且使用你定義好的 method:

<%= form_for @user, builder: MyFormBuilder do |form| %>
  <div><%= form.give_me_five %></div>
  <div><%= form.submit 'Submit' %></div>
<% end %>

你就會看到你的 form 長這樣:
https://ithelp.ithome.com.tw/upload/images/20221006/20151038ZKZR6ZTWEI.png

這樣做有什麼好處?有什麼應用範圍?

通常情況,如果我們想要在 view 使用一套邏輯來生成畫面,但又想共用,或者不想把 erb 檔弄髒,我們會定義 helper method。

但 helper method 本身其實也有他的極限,尤其當你需要額外把 |form| 這個 form builder 也一起傳入 method 去做畫面的 render 導致你傳入的 arguments 過多,導致可讀性下降的時候。

這時候,把 method 搬到 自定義 form builder 裡面,這樣你至少可以省下 form builder 以及 form object 兩個 argument,因為通過 form_for 其實就已經把你的 form object 給傳進 form builder 裡面了。

在 form builder 裡面,你可以透過 @object 這個實體變數來讀取你傳入的 form object,比如:

class MyFormBuilder < ActionView::Helpers::FormBuilder
  def welcome_message
    if @object.new_record?
      "Hello new friend!!"
    else
      "It's good to see ya!!"
    end
  end
end

然後我的 view 就可以這樣規劃:

<%= form_for @user, builder: MyFormBuilder do |form| %>
  <div><%= form.welcome_message %></div>
  <div><%= form.submit 'Submit' %></div>
<% end %>

你就會看到你的 form 長這樣:
https://ithelp.ithome.com.tw/upload/images/20221007/20151038FZaZRsGttN.png

當然,都已經繼承了,那肯定也可以 over write 像是 select , collection_check_boxes 之類的 form helper methods。這兩個筆者我都有玩過 over write XD


上一篇
D-21 Rails form bilder I18n
下一篇
D-23 如何讀取我的 active model class 已經設定的 attributes ?
系列文
Rails Active Model28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言